package com;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

public class CUSimulator extends Thread{
	private boolean m_shouldRun = true;
	private boolean m_isConnected = false;
	private String m_serverRegistrationIp;
	private int m_serverRegistrationPort;
	private Socket m_socket = null;
	private PrintWriter m_out = null;
	private BufferedReader m_in = null;
	private BufferedReader m_stdIn = null;
	private static Logger s_logger; 
	
	public CUSimulator(){
		super("CUSimulator");
		s_logger = Logger.getLogger(CUSimulator.class);
		PropertyConfigurator.configure("D:/workspace/CUSimulator/files/conf/log4j.properties");
	}
	
	public void run(){
		connectToCUServer();
		while (m_shouldRun){
			sendMessage();
			receiveMessage();			
		}
	}

	private void connectToCUServer() {
		s_logger.info("CU trying to register at server...");
		while(!m_isConnected){			
			try {
				m_serverRegistrationIp = getUserInput("Insert registrator server ip :");
				String sport = getUserInput("Insert registrator server port :");
				m_serverRegistrationPort = Integer.parseInt(sport);
				s_logger.info("CU is connecting to <" + m_serverRegistrationIp + ":" + 
						m_serverRegistrationPort + ">");
				try {					
					m_socket = new Socket(m_serverRegistrationIp, m_serverRegistrationPort);
					m_out = new PrintWriter(m_socket.getOutputStream(), true);
					m_in = new BufferedReader(new InputStreamReader(m_socket.getInputStream()));				
					m_isConnected = true;
				} catch (UnknownHostException e) {
					s_logger.fatal("CU don't know about host <" + m_serverRegistrationIp + ">");		            
				} catch (IOException e) {
					s_logger.fatal("CU couldn't get I/O for the connection to: " + 
							m_serverRegistrationIp);
				}							
			} catch (Exception e) {
				s_logger.fatal("CU failed to get server ip and port. Try again");
			}
		}
		s_logger.info("CU connected ok");
	}
	
	private void receiveMessage() {
		if(!m_shouldRun){
			return;
		}
		try {
			String receivedMsg = m_in.readLine();
			s_logger.info("Received message from server <" + receivedMsg + ">");
		} catch (IOException e) {
			s_logger.fatal("Simulator failed to receive message");
		}
	}

	private void sendMessage() {
		try {
			String command = getUserInput("Type the message for server :");
			if(command.equals("exit")){
				s_logger.info("CU get exit command");
				exitClient();				
			}
			else{
				if(command.equals("restart")){
					s_logger.info("Restart command. not implemented. try another command");
				}
				else{
					m_out.println(command);	
				}
			}

		} catch (IOException e) {
			s_logger.fatal("CU failed to get the message. try again");
		}
	}

	private String getUserInput(String string) throws IOException {
		String input;
		System.out.println(string);
		if(m_stdIn == null)
			m_stdIn = new BufferedReader(new InputStreamReader(System.in));
		input = m_stdIn.readLine();		
		return input.trim();
	}

	private void exitClient() {
		m_shouldRun = false;
		m_isConnected = false;
		m_out.println("Bye!");
		m_out.close();
		try {
			m_stdIn.close();
			m_in.close();
			m_socket.close();			
		} catch (IOException e) {
			s_logger.fatal("CU failed to close resources");
		}
		s_logger.info("Bye!");
		System.exit(0);
	}
	
	public static void main(String[] args) {
		CUSimulator cuSimulator = new CUSimulator();
		cuSimulator.start();
	}

}
